home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_0_m.arj
/
CIPHER.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-06-28
|
8KB
|
353 lines
; cipher.asm
;
; A quick low-security file encryption program, useful for deterring
; casual snoopers. Execution speed (8 MHz 80286, ST225 disk) is about
; 22000 bytes/sec.
;
; Assembly:
;
; C>masm cipher;
; C>link cipher;
; C>exe2bin cipher.exe cipher.com
; C>erase cipher.exe
;
; Usage:
;
; C>cipher filename.ext
;
; Drive and path names are allowed. Wildcards are not allowed.
; The file name must be specified completely; there is no default
; extension. The name of the file is not changed to indicate its
; plain or enciphered status.
;
; The file is enciphered in place. NO BACKUP COPY IS MADE. The
; easiest way to make a backup copy is to use CIPHER in a batch file
; with a COPY command, although this source code could also be
; modified to make a backup.
;
; The key is found in the environment strings, under KEYWORD.
; It can be set with the SET command:
;
; C>set KEYWORD=Mandarin_Orange
;
; It can be verified with the SET command:
;
; C>set
;
; This will produce a listing of the environment strings:
;
; COMSPEC=C:\COMMAND.COM
; PATH=D:\;C:\PCDOS330;C:\BINARY
; PROMPT=$t$h$h$h $n$g
; KEYWORD=Mandarin_Orange
;
; It can be cleared by rebooting or with the SET command:
;
; C>set KEYWORD=
;
DEBUG equ 0
BLOCKSIZE equ 1024
PRNG_A equ 17257 ; Shippensburg, Pennsylvania
PRNG_C equ 21545 ; Mount Savage, Maryland
codeseg segment para public 'code'
assume cs:codeseg,ds:codeseg,ss:codeseg,es:codeseg
org 0081h
cmd_line label byte
org 0100h
cipher proc near
push cs
pop ds ; ds = cs
mov ah,30h ; get DOS version number
int 21h
cmp al,2
jge look_for_keyword
mov dx,offset dos_ver_msg
jmp general_exit
; search the DOS environment for "KEYWORD=something"
; and use "something" to seed the random generator
look_for_keyword:
mov ax,ds:2ch ; get environment segment from PSP
mov es,ax ; copy it to ES
xor si,si ; start at offset = 0
env_test_line:
mov al,es:[si+1] ; peek at the next environment byte
cmp al,0 ; is it a null?
je key_error ; yes: we ran out of environment
xor bx,bx ; clear the match counter
mov di,offset key_marker ; point at key_marker
env_test_byte:
mov al,es:[si] ; get byte from environment
inc si ; point to next environment byte
mov ah,[di] ; get byte from key_marker
inc di ; point to next key_marker byte
cmp al,ah ; compare env byte to key_marker byte
jne env_skip_line ; jump on mismatch
inc bx ; increment match counter
cmp bx,marker_len ; do we have enough matches?
je env_skip_equals ; yes: jump
jmp short env_test_byte ; no: keep looking
key_error:
mov dx,offset keyword_msg
jmp general_exit
; here the current environment string is not KEYWORD
; skip to the beginning of the next line
env_skip_line:
mov al,es:[si] ; get byte from environment
inc si ; point to next environment byte
cmp al,0 ; is it a null?
jne env_skip_line ; repeat until a null is found
jmp short env_test_line ; and then go test the next line
; here es:si points to the first byte after the keyword marker
; scan past the '=' in the environment string
env_skip_equals:
mov al,es:[si] ; get byte from environment
inc si ; point to next environment byte
cmp al,0 ; end of string?
je key_error
cmp al,'=' ; find '='
jne env_skip_equals
; here es:si points to the first byte after '='
env_skip_blanks:
mov al,es:[si] ; get byte from environment
inc si ; point to next environment byte
cmp al,0 ; end of string?
je key_error
cmp al,20h ; skip over controls and spaces
jle env_skip_blanks
if DEBUG
push ax
push dx
mov ah,9 ; display string
mov dx,offset key_equ_msg
int 21h
pop dx
pop ax
endif
; here es:si points to the second byte of the key string
dec si ; point to first string byte
mov seed,0 ; clear accumulator
make_seed_loop:
mov al,es:[si] ; get byte from environment
inc si ; point to next environment byte
cmp al,20h ; exit on null or control or space
jle read_filename
cmp al,7fh ; exit on first graphic byte
jg read_filename
if DEBUG
push ax
push dx
mov ah,2 ; display character
mov dl,al
int 21h
pop dx
pop ax
endif
xor ah,ah ; clear high input byte
shl seed,1
shl seed,1
shl seed,1
add seed,ax ; accumulator += new byte
jmp short make_seed_loop
name_error:
mov dx,offset name_msg
jmp general_exit
; now get the filename from the command line
read_filename:
push cs
pop es ; es = cs
if DEBUG
push ax
push dx
mov ah,9 ; display string
mov dx,offset key_end_msg
int 21h
pop dx
pop ax
endif
mov si,offset cmd_line
skip_blanks:
lodsb ; read a byte from command line
cmp al,0dh ; check for end of line
je name_error
cmp al,20h ; check for blanks or controls
jle skip_blanks
; here si points to the second byte of the filename
dec si ; si = filename address
push si ; save filename address
skip_filename:
lodsb ; read a byte from command line
cmp al,20h ; exit on null or control or space
jg skip_filename
; here si points to the second byte after the filename
dec si ; point to first control or space
mov byte ptr [si],0 ; change it to a null
; now the filename has been found and terminated
; call DOS to open the file
mov ax,3d02h ; open file for read/write
pop dx ; dx = filename address
int 21h
mov handle,ax ; store file handle
jnc outer_loop ; carry flag indicates error
mov dx,offset open_msg
jmp general_exit
outer_loop:
mov ah,2 ; display dot on stdout
mov dl,'.'
int 21h
mov ah,3fh ; read a block from the file
mov bx,handle
mov cx,BLOCKSIZE
mov dx,offset buffer
int 21h
jc read_error
cmp ax,0 ; if the byte count was zero,
je close_and_quit ; then the file block was empty
mov byte_count,ax ; save byte count
mov cx,ax ; initialize inner loop count
mov si,offset buffer ; si = data address
mov di,si ; di = data address
mov bx,PRNG_A ; bx = multiplier
inner_loop:
mov ax,seed
mul bx
add ax,PRNG_C
mov seed,ax ; use ah for key byte
lodsb ; get a data byte
xor al,ah ; convert the data byte
stosb ; store the data byte
loop inner_loop ; repeat as necessary
mov ax,4200h ; rewind to beginning of block
mov bx,handle
mov cx,ptr_msw
mov dx,ptr_lsw
int 21h
jc seek_error
mov ah,40h ; write block back to file
mov bx,handle
mov cx,byte_count
mov dx,offset buffer
int 21h
jc write_error
mov cx,byte_count ; check for write errors
cmp ax,cx
jne write_error
cmp ax,BLOCKSIZE ; if the block was not full,
jne close_and_quit ; then we're done
add ptr_lsw,BLOCKSIZE ; find new file position
adc ptr_msw,0
jmp outer_loop ; go back for the next block
write_error:
mov dx,offset write_msg
jmp short general_exit
read_error:
mov dx,offset read_msg
jmp short general_exit
seek_error:
mov dx,offset seek_msg
jmp short general_exit
close_and_quit:
mov ah,3eh ; close file
mov bx,handle
int 21h
mov dx,offset done_msg
general_exit:
mov ah,9 ; display string
int 21h
int 20h ; return to DOS
cipher endp
key_marker db 'KEYWORD'
marker_len equ $-key_marker
done_msg db 'Done$'
name_msg db 'Filename error$'
open_msg db 'Open error$'
read_msg db 'Read error$'
seek_msg db 'Seek error$'
write_msg db 'Write error$'
keyword_msg db 'Keyword error$'
dos_ver_msg db 'Requires DOS 2.00+$'
if DEBUG
key_equ_msg db 'DEBUG: Key = "$'
key_end_msg db '"',0dh,0ah,'$'
endif
ptr_msw dw 0
ptr_lsw dw 0
handle dw 0
seed dw 0
byte_count dw 0
buffer label byte ; this goes last!
codeseg ends
end cipher